import api from './api';
import type { ChatRoom, ChatMessage, RoomInfo, CreateRoomRequest, ApiResponse, SendMessageRequest } from '../types';

// WebSocket 连接状态
let ws: WebSocket | null = null;
let reconnectAttempts = 0;
const maxReconnectAttempts = 5;
const reconnectDelay = 3000; // 3秒

// 消息回调函数集合
const messageCallbacks: Map<string, Function[]> = new Map();
const connectionCallbacks: Function[] = [];

// 聊天服务
const chatService = {
  // === API 调用相关方法 ===
  
  // 创建聊天室
  createRoom: async (data: CreateRoomRequest): Promise<RoomInfo> => {
    const response = await api.post('/rooms', data);
    return response;
  },

  // 获取聊天室列表
  getRooms: async (): Promise<RoomInfo[]> => {
    const response = await api.get('/rooms');
    return response;
  },

  // 获取聊天室信息
  getRoom: async (roomId: string): Promise<RoomInfo> => {
    const response = await api.get(`/rooms/${roomId}`);
    return response;
  },

  // 加入聊天室
  joinRoom: async (roomId: string, password?: string): Promise<void> => {
    await api.post(`/rooms/${roomId}/join`, { password });
  },

  // 离开聊天室
  leaveRoom: async (roomId: string): Promise<void> => {
    await api.post(`/rooms/${roomId}/leave`);
  },

  // 发送房间消息（API 方式）
  sendRoomMessage: async (roomId: string, content: string): Promise<ChatMessage> => {
    const response = await api.post(`/rooms/${roomId}/messages`, {
      content,
      type: 'text'
    });
    return response;
  },

  // 获取房间消息历史（API 方式）
  getRoomMessages: async (roomId: string, limit = 50, offset = 0): Promise<ChatMessage[]> => {
    const response = await api.get(`/rooms/${roomId}/messages`, {
      params: { limit, offset }
    });
    return response;
  },

  // 发送私聊消息（API 方式）
  sendPrivateMessage: async (receiverId: string, content: string): Promise<ChatMessage> => {
    const response = await api.post('/chat/private', {
      receiverId,
      content,
      type: 'text'
    });
    return response;
  },

  // 获取私聊消息历史（API 方式）
  getPrivateMessages: async (userId: string, limit = 50, offset = 0): Promise<ChatMessage[]> => {
    const response = await api.get('/chat/private', {
      params: { userId, limit, offset }
    });
    return response;
  },

  // 获取聊天会话列表
  getConversations: async (): Promise<any[]> => {
    const response = await api.get('/chat/conversations');
    return response;
  },

  // 标记消息为已读
  markAsRead: async (messageId: string): Promise<void> => {
    await api.post(`/chat/messages/${messageId}/read`);
  },

  // 踢出房间成员
  kickMember: async (roomId: string, userId: string): Promise<void> => {
    await api.post(`/rooms/${roomId}/kick`, { userId });
  },

  // 开始房间游戏
  startRoomGame: async (roomId: string): Promise<void> => {
    await api.post(`/rooms/${roomId}/game/start`);
  },

  // 结束房间游戏
  endRoomGame: async (roomId: string): Promise<void> => {
    await api.post(`/rooms/${roomId}/game/end`);
  },

  // === WebSocket 相关方法 ===
  
  // 连接 WebSocket
  connect: (token: string): Promise<void> => {
    return new Promise((resolve, reject) => {
      try {
        // 构建 WebSocket URL
        const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        const wsUrl = `${wsProtocol}//${window.location.host}/ws/chat?token=${token}`;
        
        // 创建 WebSocket 连接
        ws = new WebSocket(wsUrl);
        
        // 设置 WebSocket 事件监听器
        ws.onopen = () => {
          console.log('WebSocket 连接成功');
          reconnectAttempts = 0;
          resolve();
          // 触发所有连接回调
          connectionCallbacks.forEach(callback => callback(true));
        };
        
        ws.onmessage = (event) => {
          try {
            const data = JSON.parse(event.data);
            const { type, roomId, userId, content } = data;
            
            // 处理不同类型的消息
            switch (type) {
              case 'message':
                // 触发对应房间或用户的消息回调
                const key = roomId ? `room:${roomId}` : `user:${userId}`;
                if (messageCallbacks.has(key)) {
                  messageCallbacks.get(key)?.forEach(callback => callback(data));
                }
                // 同时触发全局消息回调
                if (messageCallbacks.has('global')) {
                  messageCallbacks.get('global')?.forEach(callback => callback(data));
                }
                break;
              
              case 'userJoined':
              case 'userLeft':
                // 触发房间事件回调
                if (roomId && messageCallbacks.has(`room:${roomId}:events`)) {
                  messageCallbacks.get(`room:${roomId}:events`)?.forEach(callback => callback(data));
                }
                break;
              
              case 'roomCreated':
              case 'roomUpdated':
                // 触发房间列表事件回调
                if (messageCallbacks.has('roomList:events')) {
                  messageCallbacks.get('roomList:events')?.forEach(callback => callback(data));
                }
                break;
              
              default:
                console.log('收到未知类型的 WebSocket 消息:', type);
            }
          } catch (error) {
            console.error('解析 WebSocket 消息失败:', error);
          }
        };
        
        ws.onclose = (event) => {
          console.log('WebSocket 连接关闭:', event.code, event.reason);
          // 触发所有连接回调
          connectionCallbacks.forEach(callback => callback(false));
          
          // 尝试重连
          if (reconnectAttempts < maxReconnectAttempts) {
            reconnectAttempts++;
            console.log(`尝试第 ${reconnectAttempts} 次重连...`);
            setTimeout(() => {
              chatService.connect(token).catch(() => {
                // 重连失败，继续尝试
              });
            }, reconnectDelay * reconnectAttempts);
          }
        };
        
        ws.onerror = (error) => {
          console.error('WebSocket 错误:', error);
          reject(error);
        };
      } catch (error) {
        console.error('WebSocket 连接失败:', error);
        reject(error);
      }
    });
  },

  // 断开 WebSocket 连接
  disconnect: (): void => {
    if (ws) {
      ws.close();
      ws = null;
    }
    // 清空所有回调
    messageCallbacks.clear();
    connectionCallbacks.length = 0;
  },

  // 检查 WebSocket 连接状态
  isConnected: (): boolean => {
    return ws !== null && ws.readyState === WebSocket.OPEN;
  },

  // 发送消息（通过 WebSocket）
  sendWsMessage: (messageData: SendMessageRequest): Promise<ApiResponse<ChatMessage>> => {
    return new Promise((resolve, reject) => {
      if (!chatService.isConnected()) {
        reject(new Error('WebSocket 未连接'));
        return;
      }
      
      try {
        ws?.send(JSON.stringify({
          type: 'message',
          ...messageData
        }));
        
        // 模拟即时成功响应（实际应用中应该等待服务端确认）
        setTimeout(() => {
          resolve({
            success: true,
            data: {
              id: `msg_${Date.now()}`,
              ...messageData,
              senderId: messageData.senderId || 'current_user',
              timestamp: new Date(),
              read: false
            } as ChatMessage
          });
        }, 100);
      } catch (error) {
        console.error('发送消息失败:', error);
        reject(error);
      }
    });
  },

  // 发送心跳包
  sendHeartbeat: (): void => {
    if (chatService.isConnected()) {
      ws?.send(JSON.stringify({ type: 'ping' }));
    }
  },

  // 加入房间（通过 WebSocket）
  joinWsRoom: (roomId: string): Promise<ApiResponse<{ message: string }>> => {
    return new Promise((resolve, reject) => {
      if (!chatService.isConnected()) {
        reject(new Error('WebSocket 未连接'));
        return;
      }
      
      try {
        ws?.send(JSON.stringify({
          type: 'joinRoom',
          roomId
        }));
        
        setTimeout(() => {
          resolve({
            success: true,
            data: { message: `已加入房间 ${roomId}` }
          });
        }, 100);
      } catch (error) {
        console.error('加入房间失败:', error);
        reject(error);
      }
    });
  },

  // 离开房间（通过 WebSocket）
  leaveWsRoom: (roomId: string): Promise<ApiResponse<{ message: string }>> => {
    return new Promise((resolve, reject) => {
      if (!chatService.isConnected()) {
        reject(new Error('WebSocket 未连接'));
        return;
      }
      
      try {
        ws?.send(JSON.stringify({
          type: 'leaveRoom',
          roomId
        }));
        
        setTimeout(() => {
          resolve({
            success: true,
            data: { message: `已离开房间 ${roomId}` }
          });
        }, 100);
      } catch (error) {
        console.error('离开房间失败:', error);
        reject(error);
      }
    });
  },

  // === 事件监听相关方法 ===
  
  // 监听房间消息
  onRoomMessage: (roomId: string, callback: (message: any) => void): (() => void) => {
    const key = `room:${roomId}`;
    if (!messageCallbacks.has(key)) {
      messageCallbacks.set(key, []);
    }
    messageCallbacks.get(key)?.push(callback);
    
    // 返回取消监听的函数
    return () => {
      const callbacks = messageCallbacks.get(key);
      if (callbacks) {
        const index = callbacks.indexOf(callback);
        if (index > -1) {
          callbacks.splice(index, 1);
        }
        if (callbacks.length === 0) {
          messageCallbacks.delete(key);
        }
      }
    };
  },

  // 监听私聊消息
  onPrivateMessage: (userId: string, callback: (message: any) => void): (() => void) => {
    const key = `user:${userId}`;
    if (!messageCallbacks.has(key)) {
      messageCallbacks.set(key, []);
    }
    messageCallbacks.get(key)?.push(callback);
    
    // 返回取消监听的函数
    return () => {
      const callbacks = messageCallbacks.get(key);
      if (callbacks) {
        const index = callbacks.indexOf(callback);
        if (index > -1) {
          callbacks.splice(index, 1);
        }
        if (callbacks.length === 0) {
          messageCallbacks.delete(key);
        }
      }
    };
  },

  // 监听所有消息
  onGlobalMessage: (callback: (message: any) => void): (() => void) => {
    const key = 'global';
    if (!messageCallbacks.has(key)) {
      messageCallbacks.set(key, []);
    }
    messageCallbacks.get(key)?.push(callback);
    
    // 返回取消监听的函数
    return () => {
      const callbacks = messageCallbacks.get(key);
      if (callbacks) {
        const index = callbacks.indexOf(callback);
        if (index > -1) {
          callbacks.splice(index, 1);
        }
        if (callbacks.length === 0) {
          messageCallbacks.delete(key);
        }
      }
    };
  },

  // 监听房间事件（用户加入/离开等）
  onRoomEvent: (roomId: string, callback: (event: any) => void): (() => void) => {
    const key = `room:${roomId}:events`;
    if (!messageCallbacks.has(key)) {
      messageCallbacks.set(key, []);
    }
    messageCallbacks.get(key)?.push(callback);
    
    // 返回取消监听的函数
    return () => {
      const callbacks = messageCallbacks.get(key);
      if (callbacks) {
        const index = callbacks.indexOf(callback);
        if (index > -1) {
          callbacks.splice(index, 1);
        }
        if (callbacks.length === 0) {
          messageCallbacks.delete(key);
        }
      }
    };
  },

  // 监听房间列表事件（房间创建/更新等）
  onRoomListEvent: (callback: (event: any) => void): (() => void) => {
    const key = 'roomList:events';
    if (!messageCallbacks.has(key)) {
      messageCallbacks.set(key, []);
    }
    messageCallbacks.get(key)?.push(callback);
    
    // 返回取消监听的函数
    return () => {
      const callbacks = messageCallbacks.get(key);
      if (callbacks) {
        const index = callbacks.indexOf(callback);
        if (index > -1) {
          callbacks.splice(index, 1);
        }
        if (callbacks.length === 0) {
          messageCallbacks.delete(key);
        }
      }
    };
  },

  // 监听连接状态变化
  onConnectionStatusChange: (callback: (connected: boolean) => void): (() => void) => {
    connectionCallbacks.push(callback);
    
    // 立即调用回调，传入当前连接状态
    callback(chatService.isConnected());
    
    // 返回取消监听的函数
    return () => {
      const index = connectionCallbacks.indexOf(callback);
      if (index > -1) {
        connectionCallbacks.splice(index, 1);
      }
    };
  },

  // === 附加功能 ===
  
  // 获取未读消息数量
  getUnreadCount: async (): Promise<ApiResponse<{ count: number }>> => {
    try {
      const response = await api.get('/chat/unread');
      return {
        success: true,
        data: { count: response.count || 0 }
      };
    } catch (error) {
      console.error('获取未读消息数量失败:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : '获取未读消息数量失败'
      };
    }
  },

  // 发送文件消息
  sendFileMessage: async (roomId: string | null, receiverId: string | null, file: File): Promise<ApiResponse<ChatMessage>> => {
    try {
      // 实际应用中应该上传文件并发送消息
      const formData = new FormData();
      formData.append('file', file);
      if (roomId) formData.append('roomId', roomId);
      if (receiverId) formData.append('receiverId', receiverId);
      
      const response = await api.post('/chat/file', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      });
      
      return {
        success: true,
        data: response
      };
    } catch (error) {
      console.error('发送文件消息失败:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : '发送文件消息失败'
      };
    }
  }
};

// 启动心跳定时器
setInterval(() => {
  if (chatService.isConnected()) {
    chatService.sendHeartbeat();
  }
}, 30000); // 每30秒发送一次心跳

export default chatService;